//
//  T3FAnnotation_Bubble.swift
//  t3_map
//
//  Created by zhu on 2024/11/21.
//

import t3_assets
import SnapKit
/// 气泡中内容的展示结构
enum T3BubbleType: String {
    /// 单文本
    case singleText
    /// 预估
    case valuation
    /// 去接乘客
    case pickupPassenger
    /// 等待乘客上车
    case waitPassenger
    /// 乘客已上车，去目的地
    case passengerOnBoard
}

class T3FBubbleAnnotationView: UIView, T3FAnnotationView {
    /// 响应点击事件
    var annotationDidClicked: (([String : Any]?) -> Void)?
    
    struct Options {
        let bubbleOptions: T3FBubbleOption?
        let imageOption: T3FImageOption?
        let textOption: T3FTextOption?

        init?(json: [String : Any]) {
            if let text = json["text"] as? [String: Any],
                let textOption = T3FTextOption(json: text) {
                self.textOption = textOption
            } else {
                self.textOption = nil
            }

            if let image = json["image"] as? [String: Any],
                let imageOption = T3FImageOption(json: image) {
                self.imageOption = imageOption
            } else {
                self.imageOption = nil
            }

            if let bubble = json["bubble"] as? [String:Any],
                let bubbleOptions = T3FBubbleOption(json: bubble) {
                self.bubbleOptions = bubbleOptions
            } else {
                self.bubbleOptions = nil
            }
        }
    }

    var options: Options

    var bubbleView: BubbleUpdateProtocol?
    var imageView: UIImageView?
    var addressTextLabel: UILabel?

    init(options: Options) {
        self.options = options
        super.init(frame: .zero)
        setupUI()
    }

    func update(argvs: [String : Any]?) {
        if let argvs = argvs,
           let bubbleOptions = T3FBubbleAnnotationView.Options(json: argvs) {
            options = bubbleOptions
            resetUI()
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()

        self.bubbleView?.clipsToBounds = true
        self.bubbleView?.layer.masksToBounds = true
        self.bubbleView?.layer.cornerRadius = (self.bubbleView?.bounds.size.height ?? 0) * 0.5
    }

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        
        if let contentView = self.bubbleView {
            let pointInContentView = contentView.convert(point, from: self)
            return contentView.point(inside: pointInContentView, with: event)
        }
        else {
            return super.point(inside: point, with: event)
        }
    }

    func resetUI() {
        imageView?.removeFromSuperview()
        bubbleView?.removeFromSuperview()
        addressTextLabel?.removeFromSuperview()

        imageView = nil
        bubbleView = nil
        addressTextLabel = nil

        setupUI()
    }

    func setupUI() {

        /// 创建视图元素
        if let imageOption = options.imageOption {
            self.imageView = createImageView(imageOption: imageOption)
        }

        if let bubbleOptions = options.bubbleOptions {
            self.bubbleView = createBubbleView(bubbleOptions: bubbleOptions)
        }

        if let textOption = options.textOption {
            self.addressTextLabel = createAddressLabel(textOption: textOption)
        }

        /// 根据视图元素进行布局
        if let imageView = self.imageView, let imageOption = options.imageOption {

            /// 布局大头针元素
            addSubview(imageView)
            imageView.snp.remakeConstraints { make in
                make.centerX.equalToSuperview()
                make.centerY.equalToSuperview().offset(-10)
                make.width.equalTo(imageOption.width)
                make.height.equalTo(imageOption.height)
            }

            /// 布局气泡元素 -- 依赖大头针元素
            if let bubbleView = self.bubbleView {
                addSubview(bubbleView)
                bubbleView.snp.remakeConstraints { make in
                    make.centerX.equalToSuperview()
                    make.bottom.equalTo(imageView.snp.top).offset(-3)
                }
            }
        }
    }

    func createImageView(imageOption: T3FImageOption) -> UIImageView {
        let imageView = UIImageView()
        imageView.image = UIImage.t3_assetsImage(name: imageOption.imageName)
        return imageView
    }

    func createBubbleView(bubbleOptions: T3FBubbleOption) -> BubbleUpdateProtocol {
        let bubbleView: BubbleUpdateProtocol
        switch bubbleOptions.bubbleType {
        case .singleText:
            bubbleView = SingleTextBubbleView(option: bubbleOptions)
        case .valuation:
            let annotationView = T3FValuationAnnotationView(option: bubbleOptions)
            annotationView.annotationDidClicked = annotationDidClicked
            bubbleView = annotationView
        default:
            bubbleView = SingleTextBubbleView(option: bubbleOptions)
            break
        }
        return bubbleView
    }

    func createAddressLabel(textOption: T3FTextOption) -> UILabel {
        let addressTextLabel = UILabel()
        addressTextLabel.numberOfLines = 2
        addressTextLabel.text = textOption.text
        addressTextLabel.textColor = textOption.normalStyle.uiColor
        addressTextLabel.font = textOption.normalStyle.uifont

        return addressTextLabel
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

protocol BubbleUpdateProtocol: UIView {
    func updateWithOption(bubbleOptions: T3FBubbleOption?)

}

class SingleTextBubbleView: UIView, BubbleUpdateProtocol {
    var option: T3FBubbleOption
    init(option: T3FBubbleOption) {
        self.option = option
        super.init(frame: .zero)
        backgroundColor = .white

        addSubview(contentLabel)
        updateWithOption(bubbleOptions: option)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    deinit {
        print("SingleTextBubbleView deinit")
    }

    lazy var contentLabel: UILabel = {
        let label = LabelCreator.createLabel(options: option.contentText)
        return label
    }()

    func updateWithOption(bubbleOptions: T3FBubbleOption?) {
        guard let bubbleOptions = bubbleOptions else {
            return
        }

        LabelCreator.updateLabel(label: contentLabel, options: bubbleOptions.contentText)
        contentLabel.snp.remakeConstraints { make in
            make.left.equalTo(12)
            make.top.equalTo(8)
            make.bottom.equalTo(-8)
            make.right.equalTo(-12)
            make.width.lessThanOrEqualTo(90)
        }
    }
}

class LabelCreator {
    class func createLabel(options: T3FTextOption?) -> UILabel {
        let label = UILabel()
        guard let options = options else {
            label.isHidden = true
            return label
        }
        label.textAlignment = .left
        label.numberOfLines = 2
        updateLabel(label: label, options: options)
        return label
    }

    class func updateLabel(label: UILabel, options: T3FTextOption) {
        let normal = T3AttributeElement(
            font: options.normalStyle.uifont,
            color: options.normalStyle.uiColor
        )
        let hilight = T3AttributeElement(
            font: options.highlightStyle.uifont,
            color: options.highlightStyle.uiColor
        )
        label.attributedText = NSAttributedString.attributeString(string: options.text, normal: normal, hilight: hilight)
    }
}
